//********************************************************************
//	created:	16:10:2011   20:49
//	filename: 	timermanager.h
//	author:		tiamo
//	purpose:	timer manager
//********************************************************************

#pragma once

namespace utils
{
	//
	// timer manager
	//
	class TimerManager
	{
	public:
		//
		// timer routine
		//
		typedef std::function<bool(uint32_t)>								TimerRoutine;

		//
		// timer
		//
		class Timer : public RefCountedObject
		{
			friend class TimerManager;

		public:
			//
			// constructor
			//
			Timer(uint32_t t, bool o, TimerRoutine&& r):mRoutine(std::move(r)) {mDelaySecond = t; mStartSecond = static_cast<uint32_t>(time(nullptr)); mOneShot = o;}

			//
			// get start time
			//
			uint32_t getStartTime() const									{return mStartSecond;}

			//
			// get fire time
			//
			uint32_t getFireTime() const									{return mStartSecond + mDelaySecond;}

		private:
			//
			// one shot
			//
			bool															mOneShot;

			//
			// start time
			//
			uint32_t														mStartSecond;

			//
			// delay time
			//
			uint32_t														mDelaySecond;

			//
			// timer routine
			//
			TimerRoutine													mRoutine;
		};

	public:
		//
		// constructor
		//
		TimerManager()														{mLastSecond = static_cast<uint32_t>(time(nullptr));}

		//
		// destructor
		//
		~TimerManager()														{}

		//
		// register timer
		//
		utils::SmartPointer<Timer> registerTimer(uint32_t delaySecond, bool oneShot, TimerRoutine&& timerRoutine);

		//
		// update timer
		//
		void updateTimer(utils::SmartPointer<Timer> const& theTimer, uint32_t delaySecond);

		//
		// unregister timer
		//
		void unregisterTimer(utils::SmartPointer<Timer> const& theTimer);

		//
		// run frame
		//
		void runFrame();

	private:
		//
		// timer list
		//
		std::list<SmartPointer<Timer>>										mTimerList;

		//
		// last time
		//
		uint32_t															mLastSecond;
	};
}
